package net.llz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import net.llz.config.RabbitMQConfig;
import net.llz.enums.BizCodeEnum;
import net.llz.enums.ProductOrderStateEnum;
import net.llz.enums.StockTaskStateEnum;
import net.llz.exception.BizException;
import net.llz.feign.ProductOrderFeignSerivce;
import net.llz.mapper.ProductMapper;
import net.llz.mapper.ProductTaskMapper;
import net.llz.model.CouponRecordMessage;
import net.llz.model.ProductDO;
import net.llz.model.ProductMessage;
import net.llz.model.ProductTaskDO;
import net.llz.request.LockProductRequest;
import net.llz.request.OrderItemRequest;
import net.llz.service.ProductService;
import net.llz.util.JsonData;
import net.llz.vo.ProductVO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {


    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductTaskMapper productTaskMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RabbitMQConfig rabbitMQConfig;

    @Autowired
    private ProductOrderFeignSerivce orderFeignSerivce;
    /**
     * 商品分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public Map<String, Object> pageProductList(int page, int size) {

        Page<ProductDO> pageInfo = new Page<>(page,size);

       IPage<ProductDO> productDOIPage =  productMapper.selectPage(pageInfo,null);

       Map<String,Object> pageMap = new HashMap<>(3);
       pageMap.put("total_record",productDOIPage.getTotal());
       pageMap.put("total_page",productDOIPage.getPages());
       pageMap.put("current_data",productDOIPage.getRecords().stream().map(obj->beanProcess(obj)).collect(Collectors.toList()));
        return pageMap;
    }

    @Override
    public ProductVO findDetailById(long productId) {

        ProductDO productDO = productMapper.selectById(productId);
//        ProductVO productVO = new ProductVO();
//        BeanUtils.copyProperties(productDO,productVO);
        return beanProcess(productDO);
    }

    /**
     * 批量设置最新价格
     * @param productIdList
     * @return
     */
    @Override
    public List<ProductVO> findProductsByIdBatch(List<Long> productIdList) {

      List<ProductDO> productDOList = productMapper.selectList(new QueryWrapper<ProductDO>().in("id",productIdList));
      List<ProductVO> productVOList = productDOList.stream().map(obj->beanProcess(obj)).collect(Collectors.toList());
        return productVOList;
    }

    /**
     * 锁定商品
     * @param lockProductRequest
     * @return
     * @throws BizException
     */
    @Override
    public JsonData lockProductStock(LockProductRequest lockProductRequest) throws BizException {

        String outTradeNo = lockProductRequest.getOrderOutTradeNo();
        List<OrderItemRequest> itemList = lockProductRequest.getOrderItemList();

        //一行代码，提取对象里面的id并加入到集合里面
        List<Long> productIdList =itemList.stream().map(OrderItemRequest::getProductId).collect(Collectors.toList());
        //批量查询
        List<ProductVO> productDOList = this.findProductsByIdBatch(productIdList);
        //分组
        Map<Long,ProductVO> productMap = productDOList.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));

        for (OrderItemRequest item : itemList){
            //锁定商品记录
            int rows =productMapper.lockProductStock(item.getProductId(), item.getBuyNum());
            if (rows != 1) {
                throw new BizException(BizCodeEnum.ORDER_CONFIRM_LOCK_PRODUCT_FAIL);
            } else {
                ProductVO productVO = productMap.get(item.getProductId());
                //插入信息
                ProductTaskDO productTaskDO = new ProductTaskDO();
                productTaskDO.setBuyNum(item.getBuyNum());
                productTaskDO.setLockState(StockTaskStateEnum.LOCK.name());
                productTaskDO.setProductId(item.getProductId());
                productTaskDO.setProductName(productVO.getTitle());
                productTaskDO.setOutTradeNo(outTradeNo);
                productTaskMapper.insert(productTaskDO);

                // 发送MQ延迟消息，介绍商品库存
                ProductMessage productMessage = new ProductMessage();
                productMessage.setTaskId(item.getProductId());
                productMessage.setOutTradeNo(outTradeNo);
                rabbitTemplate.convertAndSend(rabbitMQConfig.getEventExchange(),rabbitMQConfig.getStockReleaseDelayRoutingKey(),productMessage);
                log.info("商品库存锁定信息发送成功:{}",productMessage);
            }
        }
        return JsonData.buildSuccess();
    }


    @Override
    public boolean newProductMessage(ProductMessage productMessage) {
        //查询订单工作状态
        ProductTaskDO taskDO = productTaskMapper.selectOne(new QueryWrapper<ProductTaskDO>().eq("id",productMessage.getTaskId()));
        if (taskDO == null){
            log.warn("工作单不存在，消息体为:{}",productMessage);
        }
        //lock状态才处理
        if (taskDO.getLockState().equalsIgnoreCase(StockTaskStateEnum.LOCK.name())){
            JsonData jsonData = orderFeignSerivce.queryProductOrderState(productMessage.getOutTradeNo());


            if(jsonData.getCode() == 0) {
                String state = jsonData.getData().toString();
                //查询订单状态
                if (ProductOrderStateEnum.NEW.name().equalsIgnoreCase(state)) {
                    log.warn("订单状态是NEW,返回给消息队列，重新投递:{}", productMessage);
                    return false;
                }

                //如果订单已经支付
                if (ProductOrderStateEnum.PAY.name().equalsIgnoreCase(state)) {
                    taskDO.setLockState(StockTaskStateEnum.FINISH.name());
                    productTaskMapper.update(taskDO,new QueryWrapper<ProductTaskDO>().eq("id",productMessage.getTaskId()));
                    log.info("订单已经支付，修改库存锁定工作单FINISH状态:{}",productMessage);
                    return true;
                }
            }
            //订单不存在，或者订单被取消，确认消息,修改task状态为CANCEL,恢复优惠券使用记录为NEW
            log.warn("订单不存在，或者订单被取消，确认消息,修改task状态为CANCEL,恢复商品库存,message:{}",productMessage);
            taskDO.setLockState(StockTaskStateEnum.CANCEL.name());
            //恢复商品库存，集锁定库存的值减去当前购买的值
            productMapper.unlockProductStock(taskDO.getProductId(),taskDO.getBuyNum());
            return true;

        }else {
            log.warn("工作单状态不是LOCK,state={},消息体={}",taskDO.getLockState(),productMessage);
            return true;
        }
    }



    private ProductVO beanProcess(ProductDO productDO) {

        ProductVO productVO = new ProductVO();
        BeanUtils.copyProperties(productDO,productVO);
        return productVO;
    }
}
